package store.lunangangster.engine.impl.entity.mgr;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import store.lunangangster.engine.ProcessEngineConfiguration;
import store.lunangangster.engine.impl.Context;
import store.lunangangster.engine.impl.db.DbSqlSession;
import store.lunangangster.engine.impl.entity.Entity;
import store.lunangangster.engine.impl.repository.EntityMatcher;

/**
 * 对{@link EntityManager}中的通用抽象方法的实现
 *
 * @author cwk
 * @version 1.0
 */
public abstract class AbstractEntityManagerImpl<T extends Entity> extends AbstractManager implements EntityManager<T> {

  public AbstractEntityManagerImpl(ProcessEngineConfiguration processEngineConfiguration) {
    super(processEngineConfiguration);
  }

  /**
   * 获取实体管理类实际管理的实现类
   */
  public abstract Class<? extends T> getManagedEntityClass();

  @Override
  public void batchInsert(Collection<T> entities) {
    getDbSqlSession().batchInsert(entities);
  }

  @Override
  public void insert(T entity) {
    getDbSqlSession().insert(entity);
  }

  @Override
  public T selectById(String id) {
    return (T) getDbSqlSession().selectById(getManagedEntityClass(), id);
  }

  @Override
  public T selectOne(String statement, Object parameter, EntityMatcher<T> matcher) {
    List<T> list = selectList(statement, parameter, matcher);
    if (list == null || list.isEmpty()) {
      return null;
    }
    return list.get(0);
  }

  @Override
  @SuppressWarnings("unchecked")
  public List<T> selectList(String statement, Object parameter, EntityMatcher<T> matcher) {
    List<T> list = (List<T>) getDbSqlSession().selectList(statement, parameter);

    List<T> result = new ArrayList<>(list.size());
    for (T entity : list) {
      if (matcher == null || matcher.match(parameter, entity)) {
        result.add(entity);
      }
    }
    result.removeIf(Entity::isDelete);
    return result;
  }

  @Override
  public void delete(String id) {
    getDbSqlSession().delete(getManagedEntityClass(), id);
  }

  @Override
  public void delete(T entity) {
    getDbSqlSession().delete(entity);
  }

  @Override
  public void deleteBatch(List<String> ids) {
    Class<? extends T> clazz = getManagedEntityClass();
    for (String id : ids) {
      getDbSqlSession().delete(clazz, id);
    }
  }

  protected DbSqlSession getDbSqlSession() {
    return Context.getCommandContext().getDbSqlSession();
  }
}
